/**触发视图更新 */
function updateView() {
  console.log("视图更新");
}

/**属性劫持，实现监听 */
function defineReactive(target, key, value) {
  // 核心 API
  Object.defineProperty(target, key, {
    get() {
      return value;
    },
    set(newValue) {
      if (newValue !== value) {
        // 设置新值
        // 注意，value一直在闭包中，此处设置完之后，再 get 时也会获取最新的值
        value = newValue;

        // 触发更新视图
        updateView();
      }
    },
  });
}

/**监听对象属性 */
function observer(target) {
  if (typeof target !== "object" || target === null) {
    // 不是对象或数组
    return target;
  }

  // 重新定义各个属性（for in 也可以遍历数组）
  for (let key in target) {
    defineReactive(target, key, target[key]);
  }
}

// 准备数据
const data = {
  name: "zhagnsan",
  age: 20,
  // info: {
  //   addredd: "北京",
  // },
  // nums: [10, 20, 30],
};

// 监听数据
observer(data);

// 测试
data.name = "lisi";
data.age = 21;
data.x = "100"; // 新增的属性，监听不到，所以有 Vue.set
// delete data.name; // 删除属性，监听不到，所以有 Vue.delete
// data.info.address = "上海"; // 深度监听
// data.nums.push(40); // 监听数组
